package com.sskj.postar.controller;

import com.sskj.postar.core.ret.HttpResponse;
import com.sskj.postar.core.ret.HttpResult;
import com.sskj.postar.enums.FabiTradeOrderStatusEnum;
import com.sskj.postar.enums.SysConfigEnum;
import com.sskj.postar.model.*;
import com.sskj.postar.service.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/fabi")
public class FabiController {
    @Resource
    UserService userService;
    @Resource
    SystemConfigService systemConfigService;
    @Resource
    FabiPublishService fabiPublishService;
    @Resource
    UserAssetService userAssetService;
    @Resource
    UserPayInfoService userPayInfoService;
    @Resource
    FabiService fabiService;
    @Resource
    FabiTradeService fabiTradeService;


    /**
     * 商家发布单子
     *
     * @param coin     币种类型
     * @param type     出售单子 1 求购单子 2
     * @param maxMoney 最大限额
     * @param minMoney 最小限额
     * @param price    单价
     * @param number   数量
     * @param remark   备注
     * @param payType  支付方式 1,2,3 1 微信 2 支付宝 3 银行卡
     * @return
     */
    @PostMapping("/publish")
    public HttpResult publish(@RequestParam(name = "coin", required = false, defaultValue = "USDT") String coin,
                              int type, String maxMoney, String minMoney, String price, String number,
                              @RequestParam(name = "remark", required = false) String remark,
                              @RequestParam(name = "payType", required = false) String payType,
                              HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        FabiPublish fabiPublish = new FabiPublish();
        fabiPublish.setUserId(user.getId());
        fabiPublish.setCoin(coin);
        fabiPublish.setLeftNum(number);
        fabiPublish.setMaxMoney(maxMoney);
        fabiPublish.setMinMoney(minMoney);
        fabiPublish.setType(type);
        if (type == 2) {//发布出售，需要有支付方式
            //拥有足够的币
            UserAsset userAssetQuery = new UserAsset();
            userAssetQuery.setUserId(user.getId());
            userAssetQuery.setType(coin);
            UserAsset userAsset = userAssetService.selectOne(userAssetQuery);
            if (userAsset == null || new Double(userAsset.getAvailable()) < Double.valueOf(number)) {
                return HttpResponse.makeErrRsp(String.format("账户%s不足", coin));
            }
            //添加过支付方式
            if (payType == null) {
                return HttpResponse.makeErrRsp("参数缺少,payType");
            }
            UserPayInfo userPayInfoQuery = new UserPayInfo();
            userPayInfoQuery.setUserId(user.getId());
            userPayInfoQuery.setIsOpen(true);
            List<UserPayInfo> userPayInfos = userPayInfoService.select(userPayInfoQuery);
            if (userPayInfos != null) {
                boolean isPayTypeError = false;
                String[] split = payType.split(",");
                for (String s : split) {
                    boolean isContain = false;
                    for (UserPayInfo userPayInfo : userPayInfos) {
                        if (userPayInfo.getPayType().equals(s)) {
                            if (!isContain) {
                                isContain = true;
                            } else {
                                isPayTypeError = true;
                                break;
                            }
                        }
                    }
                    if (!isPayTypeError) {
                        isPayTypeError = !isContain;
                    }
                }
                if (isPayTypeError) {
                    return HttpResponse.makeErrRsp("支付方式异常");
                }
            }
            fabiPublish.setPayType(payType);
        }
        fabiPublish.setPublishNum(number);
        fabiPublish.setRemark(remark);
        fabiPublish.setPrice(price);
        fabiPublishService.publish(fabiPublish);
        return HttpResponse.makeOKRsp("发单成功", null);
    }

    /**
     * 获取大厅列表
     *
     * @param coin 币种类型
     * @param type 1 商家发布的出售单 2 商家发布的求购单
     * @return
     */
    @PostMapping("/getMarketByType")
    public HttpResult getMarketByType(@RequestParam(name = "coin", required = false, defaultValue = "USDT") String coin,
                                      int type) {
        FabiPublish fabiPublish = new FabiPublish();
        fabiPublish.setType(type);
        fabiPublish.setCoin(coin);
        List<Map> fabiMarketBeans = fabiPublishService.selectMarketByType(fabiPublish);
        return HttpResponse.makeOKRsp(fabiMarketBeans);
    }

    /**
     * 下单
     *
     * @param id       单子id
     * @param allMoney 总金额
     * @param num      总数量
     * @param payPwd   交易密码
     * @param payType  支付方式 逗号隔开， wx alipay bank
     * @return
     */
    @PostMapping("/trade")
    public HttpResult trade(HttpServletRequest request, String id, String allMoney,
                            String num, String payPwd,
                            @RequestParam(name = "payType", required = false) String payType) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        if (user.getPayPwd() == null) {
            return HttpResponse.makeErrRsp("请先设置支付密码");
        }
        if (!user.getPayPwd().equals(payPwd)) {
            return HttpResponse.makeErrRsp("支付密码错误");
        }
        FabiPublish fabiPublish = fabiPublishService.selectById(id);
        if (fabiPublish == null) {
            return HttpResponse.makeErrRsp("交易单子不存在");
        }
        if (fabiPublish.getUserId().equals(user.getId())) {
            return HttpResponse.makeErrRsp(String.format("不能%s自己的单子", fabiPublish.getType() == 2 ? "购买" : "出售"));
        }
        if (new BigDecimal(fabiPublish.getLeftNum()).doubleValue() < new BigDecimal(num).doubleValue()) {
            return HttpResponse.makeErrRsp("单子剩余数目不足");
        }
        if (fabiPublish.getType() == 1) {//出售
            //支付方式校验
            //用户资金校验
            //添加过支付方式
            if (payType == null) {
                return HttpResponse.makeErrRsp("参数缺少,payType");
            }
            UserPayInfo userPayInfoQuery = new UserPayInfo();
            userPayInfoQuery.setUserId(user.getId());
            userPayInfoQuery.setIsOpen(true);
            List<UserPayInfo> userPayInfos = userPayInfoService.select(userPayInfoQuery);
            if (userPayInfos != null) {
                boolean isPayTypeError = false;
                String[] split = payType.split(",");
                for (String s : split) {
                    boolean isContain = false;
                    for (UserPayInfo userPayInfo : userPayInfos) {
                        if (userPayInfo.getPayType().equals(s)) {
                            if (!isContain) {
                                isContain = true;
                            } else {
                                isPayTypeError = true;
                                break;
                            }
                        }
                    }
                    if (!isPayTypeError) {
                        isPayTypeError = !isContain;
                    }
                }
                if (isPayTypeError) {
                    return HttpResponse.makeErrRsp("支付方式异常");
                }
            }


            SystemConfig systemConfig = systemConfigService.selectOne(SysConfigEnum.FABI_FEE.systemConfig);
            BigDecimal fee = new BigDecimal(systemConfig.getValue());
            BigDecimal numBig = new BigDecimal(num).add(new BigDecimal(num).multiply(fee));
            UserAsset userAssetQuery = new UserAsset();
            userAssetQuery.setUserId(user.getId());
            userAssetQuery.setType(fabiPublish.getCoin());
            UserAsset userAsset = userAssetService.selectOne(userAssetQuery);
            if (userAsset == null || new BigDecimal(userAsset.getAvailable()).doubleValue() < numBig.doubleValue()) {
                return HttpResponse.makeErrRsp(String.format("资金%s不足", fabiPublish.getCoin()));
            }
            // TODO: 18-12-20 防并发，多人对同一单下单
             /* 开启事务处理
             1.冻结用户该币种资金
             2.更改商家发布单剩余数量
             3.生成交易订单
             */
            fabiService.tradeSell(numBig, userAsset, fabiPublish, num, payType);
        }else {//购买
            fabiService.tradeBuy(user,fabiPublish,num);
        }
        return HttpResponse.makeOKRsp("成功", null);
    }

    /**
     * 获取匹配单子列表
     *
     * @param status 状态
     * @param id     订单id
     * @return
     */
    @PostMapping("/getTradeOrder")
    public HttpResult getTradeOrder(@RequestParam(required = false) Integer status,
                                    @RequestParam(required = false) Integer id,HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        FabiTrade fabiTradeQuery = new FabiTrade();
        fabiTradeQuery.setStatus(status);
        fabiTradeQuery.setId(id);
        fabiTradeQuery.setSellerId(user.getId());
        fabiTradeQuery.setBuyyerId(user.getId());

        List<FabiTrade> select = fabiTradeService.selectMyOrder(fabiTradeQuery);
        select.forEach(fabiTrade -> {
            List<UserPayInfo> userPayInfos = new ArrayList<>();
            fabiTrade.setUserPayInfos(userPayInfos);
            String[] payTypes = fabiTrade.getSellerPayType().split(",");
            Integer sellerId = fabiTrade.getSellerId();
            for (String payType : payTypes) {
                UserPayInfo userPayInfoQuery = new UserPayInfo();
                userPayInfoQuery.setUserId(sellerId);
                userPayInfoQuery.setPayType(payType);
                UserPayInfo userPayInfo = userPayInfoService.selectOne(userPayInfoQuery);
                fabiTrade.getUserPayInfos().add(userPayInfo);
            }
            Date currentDate = new Date();
            long currentSeconds = currentDate.getTime() / 1000;
            long leftTime = currentSeconds - Long.valueOf(fabiTrade.getCreateTime());
            SystemConfig systemConfig = systemConfigService.selectOne(SysConfigEnum.FABI_PAY_TIME.systemConfig);
            leftTime = Long.valueOf(systemConfig.getValue()) - leftTime;
            fabiTrade.setLeftDownTime(leftTime >= 0 ? leftTime : 0);
        });
        return HttpResponse.makeOKRsp("成功", select);
    }

    public HttpResult markPay(HttpServletRequest request,String id){
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        FabiTrade fabiTrade = fabiTradeService.selectById(id);
        if (fabiTrade==null){
            return HttpResponse.makeErrRsp("订单不存在");
        }
        if (fabiTrade.getSellerId().intValue()==user.getId()&&fabiTrade.getStatus()==2){
            // TODO: 18-12-21
            /**
             * 订单完成
             * 卖家 冻结金额减少
             * 设置完成时间，更改订单状态
             * 如果发布单剩余数量为0,且没有交易中的匹配单子，更改发布订单状态
             */
            FabiTrade fabiTradeUpdate = new FabiTrade();
            fabiTradeUpdate.setCompleteTime((new Date().getTime()/1000)+"");
            fabiTradeUpdate.setStatus(FabiTradeOrderStatusEnum.COMPLETE.getCode());

        }
        return null;

    }


}
